package jp.co.nes.awssupport.business.logic;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.YearMonth;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import jp.co.nes.awssupport.access.dao.MonthlyCompiledBillingDao;
import jp.co.nes.awssupport.common.bean.DailyCompiledBillingBean;
import jp.co.nes.awssupport.common.bean.MonthlyCompiledBillingBean;
import jp.co.nes.awssupport.common.utility.DateUtil;

/**
 * 月次集計結果処理です。
 */
public class MonthlyCompiledBillingProcessing {

    /** 処理対象年月 */
    private YearMonth targetYearMonth;

    /** 連結アカウントID */
    private String linkedAccountId;

    /** 日次集計結果リスト */
    private List<DailyCompiledBillingBean> csvList = new ArrayList<>();

    /**
     * 処理対象年月を引数にもつコンストラクタです。
     *
     * @param targetYearMonth 処理対象年月
     * @param linkedAccountId 連結アカウントID
     */
    public MonthlyCompiledBillingProcessing(YearMonth targetYearMonth, String linkedAccountId) {
        this.targetYearMonth = targetYearMonth;
        this.linkedAccountId = linkedAccountId;
    }

    /**
     * 月次集計結果を削除します。
     */
    public void delete() {
        MonthlyCompiledBillingDao dao = new MonthlyCompiledBillingDao();
        dao.delete(linkedAccountId, targetYearMonth);
    }

    /**
     * 日次集計結果を追加します。
     *
     * @param dcbBean 日次集計結果
     */
    public void add(DailyCompiledBillingBean dcbBean) {
        csvList.add(dcbBean);
    }

    /**
     * 請求CSVリストをクリアします。
     */
    public void clear() {
        csvList.clear();
    }
    /**
     * 月次集計結果を登録します。
     *
     * @param max バッチ更新の最大数
     */
    public void insert(int max) {
        MonthlyCompiledBillingDao dao = new MonthlyCompiledBillingDao();
        dao.insert(toMonthlyCompiledBillingList(), max);
    }

    /**
     * 月次集計結果リストを返却します。
     *
     * @return 月次集計結果リスト
     */
    private List<MonthlyCompiledBillingBean> toMonthlyCompiledBillingList() {
        return csvList.stream().map(csvBean -> toMonthlyCompiledBilling(csvBean)).collect(Collectors.toList());
    }

    /**
     * 月次集計結果を返却します。
     *
     * @param dcbBean 日次集計結果
     * @return 月次集計結果
     */
    private MonthlyCompiledBillingBean toMonthlyCompiledBilling(DailyCompiledBillingBean dcbBean) {
        MonthlyCompiledBillingBean mcbBean = new MonthlyCompiledBillingBean();
        mcbBean.setLinkedAccountId(dcbBean.getLinkedAccountId());
        mcbBean.setYearMonth(DateUtil.toInt(targetYearMonth));
        mcbBean.setProductName(dcbBean.getProductName());
        mcbBean.setUsageType(dcbBean.getUsageType());
        mcbBean.setRate(dcbBean.getRate());
        mcbBean.setUsageQuantity(dcbBean.getUsageQuantity());
        mcbBean.setBillingAmount(calcBillingAmount(dcbBean));
        mcbBean.setDescription(dcbBean.getDescription());
        mcbBean.setUnit(dcbBean.getUnit());
        return mcbBean;
    }

    /**
     * 請求額(税抜)を計算し、返却します。
     *
     * @param csvBean 請求CSV
     * @return 請求額(税抜)
     */
    private BigDecimal calcBillingAmount(DailyCompiledBillingBean dcbBean) {
        BigDecimal usageQuantity = dcbBean.getUsageQuantity();
        BigDecimal rate = dcbBean.getRate();
        // 請求額 = 使用量 * レート (小数点第11位で四捨五入)
        return usageQuantity.multiply(rate).setScale(10, RoundingMode.HALF_UP);
    }
}
